import os  # 导入操作系统模块，用于处理文件和目录
import pygame  # 导入Pygame模块，用于音频播放
from datetime import datetime  # 导入datetime模块，用于处理日期和时间

# 初始化Pygame的混音器模块
pygame.mixer.init()

# 从指定文件夹中读取歌曲列表
def read_songs_from_folder(folder_path):
    try:
        # 获取文件夹中的所有文件名，筛选出文件而非子文件夹
        songs = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
        # 如果歌曲超过20首，只返回前20首
        if len(songs) > 20:
            return songs[:20]
        return songs  # 返回歌曲列表
    except Exception as e:
        print(f"读取文件夹失败: {str(e)}")  # 捕获异常并打印错误信息
        return []  # 返回空列表表示读取失败

# 显示操作菜单
def show_menu():
    print("\n欢迎来到荷兰猪的KTV")
    print("===================================")
    print("1. 搜索歌曲")
    print("2. 选择歌曲")
    print("3. 移除歌曲")
    print("4. 显示已选歌曲")
    print("5. 播放歌曲")
    print("6. 暂停/继续播放")
    print("7. 停止播放")
    print("8. 播放下一首")
    print("9. 设置音量")
    print("10. 显示播放历史")
    print("11. 显示歌词")
    print("12. 切换循环播放")
    print("0. 退出")
    print("===================================")

# 搜索歌曲
def search_song(songs):
    search_keyword = input("请输入搜索关键字: ").lower()  # 获取用户输入的搜索关键字
    matching_songs = [song for song in songs if search_keyword in song.lower()]  # 匹配关键字的歌曲
    print("搜索结果:")
    for song in matching_songs:  # 打印匹配结果
        print(song)
    return matching_songs  # 返回匹配的歌曲列表

# 选择歌曲
def select_song(songs, selected_songs):
    song_name = input("请输入要选择的歌曲名: ")  # 获取用户输入的歌曲名
    if song_name in songs:  # 检查歌曲是否在可选列表中
        selected_songs.append(song_name)  # 将歌曲添加到已选列表中
        print(f"已选择歌曲: {song_name}")
    else:
        print("歌曲未找到，请确认输入的歌曲名是否正确。")

# 移除已选歌曲
def remove_song(selected_songs):
    song_name = input("请输入要移除的歌曲名: ")  # 获取用户输入的歌曲名
    if song_name in selected_songs:  # 检查歌曲是否在已选列表中
        selected_songs.remove(song_name)  # 从已选列表中移除歌曲
        print(f"已移除歌曲: {song_name}")
    else:
        print("歌曲未找到，请确认输入的歌曲名是否正确。")

# 显示已选歌曲列表
def show_selected_songs(selected_songs):
    if selected_songs:  # 检查已选列表是否为空
        print("已选歌曲列表:")
        for idx, song in enumerate(selected_songs, 1):  # 枚举已选歌曲并打印
            print(f"{idx}. {song}")
    else:
        print("暂无已选歌曲")

# 播放歌曲
def play_song(folder_path, selected_songs, play_history):
    if not selected_songs:  # 检查是否有已选歌曲
        print("没有已选歌曲，请先选择歌曲。")
        return

    current_song = selected_songs[0]  # 获取当前要播放的歌曲
    try:
        pygame.mixer.music.load(os.path.join(folder_path, current_song))  # 加载歌曲文件
        pygame.mixer.music.play()  # 播放歌曲
        update_play_history(current_song, play_history)  # 更新播放历史
        display_lyrics(folder_path, current_song)  # 显示歌词
        print(f"正在播放: {current_song}")
        check_song_end(folder_path, selected_songs, play_history)  # 检查歌曲播放结束
    except Exception as e:
        print(f"无法播放歌曲: {str(e)}")

# 暂停或继续播放歌曲
def pause_song():
    if pygame.mixer.music.get_busy():  # 检查是否有歌曲正在播放
        pygame.mixer.music.pause()  # 暂停播放
        print("播放已暂停")
    else:
        pygame.mixer.music.unpause()  # 继续播放
        print("继续播放")

# 停止播放歌曲
def stop_song():
    pygame.mixer.music.stop()  # 停止播放
    print("播放已停止")

# 播放下一首歌曲
def play_next_song(folder_path, selected_songs, play_history):
    if selected_songs:  # 检查是否有已选歌曲
        stop_song()  # 停止当前播放的歌曲
        selected_songs.pop(0)  # 从已选列表中移除当前播放的歌曲
        if selected_songs:  # 检查是否还有剩余的已选歌曲
            play_song(folder_path, selected_songs, play_history)  # 播放下一首歌曲
        else:
            print("已选歌曲列表已空。")
    else:
        print("没有已选歌曲，请先选择歌曲。")

# 设置音量
def set_volume():
    try:
        volume = float(input("请输入音量(0.0-1.0): "))  # 获取用户输入的音量值
        if 0.0 <= volume <= 1.0:  # 检查音量值是否在有效范围内
            pygame.mixer.music.set_volume(volume)  # 设置音量
            print(f"音量设置为: {volume}")
        else:
            print("音量输入无效，请输入0.0到1.0之间的值。")
    except ValueError:
        print("输入无效，请输入数字。")

# 更新播放历史记录
def update_play_history(song_name, play_history):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")  # 获取当前时间的时间戳
    play_history.append(f"{timestamp}: {song_name}")  # 将播放记录添加到历史记录中
    if len(play_history) > 20:  # 如果历史记录超过20条，移除最早的一条
        play_history.pop(0)

# 显示播放历史记录
def show_play_history(play_history):
    if play_history:  # 检查是否有播放历史
        print("播放历史记录:")
        for record in play_history:  # 打印所有播放历史记录
            print(record)
    else:
        print("暂无播放历史记录")

# 显示歌词
def display_lyrics(folder_path, song_name):
    lyrics_file = os.path.splitext(song_name)[0] + ".txt"  # 获取歌词文件名
    lyrics_path = os.path.join(folder_path, lyrics_file)  # 获取歌词文件路径
    if os.path.exists(lyrics_path):  # 检查歌词文件是否存在
        with open(lyrics_path, "r", encoding="utf-8") as f:  # 打开歌词文件
            lyrics = f.read()  # 读取歌词内容
        print("歌词:")
        print(lyrics)  # 打印歌词
    else:
        print("没有找到歌词")

# 切换循环播放模式
def toggle_repeat():
    repeat = pygame.mixer.music.get_endevent()  # 获取当前的循环播放设置
    if repeat:  # 如果当前是循环播放模式
        pygame.mixer.music.set_endevent(None)  # 关闭循环播放
        print("循环播放已关闭")
    else:  # 如果当前不是循环播放模式
        pygame.mixer.music.set_endevent(pygame.constants.USEREVENT)  # 开启循环播放
        print("循环播放已开启")

# 检查歌曲是否播放完毕
def check_song_end(folder_path, selected_songs, play_history):
    while pygame.mixer.music.get_busy():  # 检查歌曲是否正在播放
        pygame.time.wait(1000)  # 等待1秒
    play_next_song(folder_path, selected_songs, play_history)  # 播放下一首歌曲

# 主程序入口
if __name__ == "__main__":
    folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "音效")  # 获取音效文件夹路径
    songs = read_songs_from_folder(folder_path)  # 读取歌曲列表
    selected_songs = []  # 初始化已选歌曲列表
    play_history = []  # 初始化播放历史记录列表

    while True:
        show_menu()  # 显示操作菜单
        choice = input("请输入选项: ")  # 获取用户输入的操作选项
        if choice == "1":
            search_song(songs)  # 搜索歌曲
        elif choice == "2":
            select_song(songs, selected_songs)  # 选择歌曲
        elif choice == "3":
            remove_song(selected_songs)  # 移除已选歌曲
        elif choice == "4":
            show_selected_songs(selected_songs)  # 显示已选歌曲列表
        elif choice == "5":
            play_song(folder_path, selected_songs, play_history)  # 播放歌曲
        elif choice == "6":
            pause_song()  # 暂停或继续播放歌曲
        elif choice == "7":
            stop_song()  # 停止播放歌曲
        elif choice == "8":
            play_next_song(folder_path, selected_songs, play_history)  # 播放下一首歌曲
        elif choice == "9":
            set_volume()  # 设置音量
        elif choice == "10":
            show_play_history(play_history)  # 显示播放历史记录
        elif choice == "11":
            if selected_songs:
                display_lyrics(folder_path, selected_songs[0])  # 显示歌词
            else:
                print("暂无已选歌曲")
        elif choice == "12":
            toggle_repeat()  # 切换循环播放模式
        elif choice == "0":
            print("感谢使用荷兰猪的KTV，再见！")  # 退出程序
            break
        else:
            print("无效选项，请重新输入")  # 提示无效选项
